<?php


namespace app\common\library;


use common;
use app\common\library\PlatformModel;
use think\facade\Env;
use think\facade\Log;


require_once   Env::get('extend_path')."/alipay-sdk-PHP-3.4.0/aop/AopClient.php";
require_once   Env::get('extend_path')."/alipay-sdk-PHP-3.4.0/aop/SignData.php";
require_once   Env::get('extend_path')."/alipay-sdk-PHP-3.4.0/aop/request/AlipaySystemOauthTokenRequest.php";
require_once   Env::get('extend_path')."/alipay-sdk-PHP-3.4.0/aop/request/AlipayUserInfoShareRequest.php";
require_once   Env::get('extend_path')."/alipay-sdk-PHP-3.4.0/aop/request/AlipayTradeCreateRequest.php";
require_once   Env::get('extend_path')."/alipay-sdk-PHP-3.4.0/aop/request/AlipayTradeRefundRequest.php";
require_once   Env::get('extend_path')."/alipay-sdk-PHP-3.4.0/aop/request/AlipayDataDataserviceBillDownloadurlQueryRequest.php";
require_once   Env::get('extend_path')."/alipay-sdk-PHP-3.4.0/aop/request/AlipayTradeAppPayRequest.php";
require_once   Env::get('extend_path')."/alipay-sdk-PHP-3.4.0/aop/request/AlipayTradeOrderSettleRequest.php";
require_once   Env::get('extend_path')."/alipay-sdk-PHP-3.4.0/aop/request/AlipayTradeRoyaltyRelationBindRequest.php";
require_once   Env::get('extend_path')."/alipay-sdk-PHP-3.4.0/aop/request/AlipayTradeRoyaltyRelationUnbindRequest.php";
require_once   Env::get('extend_path')."/alipay-sdk-PHP-3.4.0/aop/request/AlipayTradeRoyaltyRelationBatchqueryRequest.php";

class AlimpModel
{
    var $_appid = null;
    var $_rsa_private_key_path = null;
    var $_rsa_public_key = null;
    var $_gateway = 'https://openapi.alipay.com/gateway.do';
    var $_notify_url = null;
    var $_refund_notify_url = null;
    var $_aeskey = null;

    function __construct($city_id = null)
    {
        if (empty($city_id)){
            $platform_info = (new PlatformModel())->get_platform_info('alimpu');
            $this->_appid = $platform_info['appid'];
            $this->_rsa_private_key_path = $platform_info['private_key_path'];
            $this->_rsa_public_key = $platform_info['public_key'];
            $this->_aeskey = $platform_info['aeskey'];
            global $g_env;
            if ($g_env != 'ONLINE') {
                // $this->_gateway = 'https://openapi.alipaydev.com/gateway.do';
            }

            $cfg = config('app.alipay');
            $this->_notify_url = $cfg['notify_url'];
            $this->_refund_notify_url = $cfg['refund_notify_url'];
        }
        else{
            $platform_info = (new PlatformModel())->get_city_al_token($city_id);
            $this->_appid = $platform_info['alipay']['appid'];
            $this->_rsa_private_key_path = $platform_info['alipay']['private_key_path'];
            $this->_rsa_public_key = $platform_info['alipay']['public_key'];
            $this->_aeskey = $platform_info['alipay']['aeskey'];
            global $g_env;
            if ($g_env != 'ONLINE') {
                // $this->_gateway = 'https://openapi.alipaydev.com/gateway.do';
            }

            $this->_notify_url = $platform_info['alipay']['notify_url'];
            $this->_refund_notify_url = $platform_info['alipay']['refund_notify_url'];
        }

    }

    function user_info_share($access_token)
    {
        $aop = $this->aop();
        $request = new AlipayUserInfoShareRequest();
        $result = $aop->execute($request, $access_token);

        $result = common::object_to_array($result);

        Log::debug($result);

        $responseNode = str_replace(".", "_", $request->getApiMethodName()) . "_response";
        if (!isset($result[$responseNode])) {
            hilog::debug($result);
            return null;
        }

        $resp = $result[$responseNode];

        if (!isset($resp['code']) || $resp['code'] != 10000) {
            Log::debug($result);
            return null;
        }

        $item = [
            'user_id' => $resp['user_id'],
            'avatar' => $resp['avatar'],
            'province' => $resp['province'],
            'city' => $resp['city'],
            'nick_name' => $resp['nick_name'],
            'is_student_certified' => $resp['is_student_certified'],
            'user_type' => $resp['user_type'],
            'user_status' => $resp['user_status'],
            'is_certified' => $resp['is_certified'],
            'gender' => $resp['gender'],
        ];
        return $item;
    }

    function auth_token_to_access_token($code)
    {
        $aop = $this->aop();
        $request = new AlipaySystemOauthTokenRequest ();
        $request->setGrantType("authorization_code");
        $request->setCode($code);

        $result = $aop->execute($request);


        $result = common::object_to_array($result);


        $responseNode = str_replace(".", "_", $request->getApiMethodName()) . "_response";

        if (!isset($result[$responseNode])) {
            Log::error('auth_token_to_access_token'.$result);
            return null;
        }

        $resp = $result[$responseNode];

        if (!isset($resp['access_token'])) {
            Log::error('auth_token_to_access_token',$result);
            return null;
        }
        Log::debug('auth_token_to_access_token', $result);
        $item = [
            'access_token' => $resp['access_token'],
            'alipay_user_id' => $resp['alipay_user_id'],
            'expires_in' => $resp['expires_in'],
            're_expires_in' => $resp['re_expires_in'],
            'refresh_token' => $resp['refresh_token'],
            'user_id' => $resp['user_id'],
        ];
        return $item;
    }

    /**
     *
     * @return \AopClient
     */
    function aop()
    {
        $aop = new AopClient();
        $aop->gatewayUrl = $this->_gateway;
        $aop->appId = $this->_appid;
        $aop->rsaPrivateKeyFilePath = $this->_rsa_private_key_path;
        $aop->alipayrsaPublicKey = $this->_rsa_public_key;
        $aop->apiVersion = '1.0';
        $aop->signType = 'RSA2';
        $aop->postCharset = 'UTF-8';
        $aop->format = 'json';
        return $aop;
    }

    function create_trade($out_order_no, $alipay_user_id, $amount, $subject,$pay_city)
    {
        $aop = $this->aop();
        $request = new AlipayTradeCreateRequest ();

        $passback_params = "pay_city=".$pay_city;
        $bizContent = [
            'out_trade_no' => $out_order_no,
            'total_amount' => $amount / 100,
            'subject' => $subject,
            'buyer_id' => $alipay_user_id,
//            'passback_params'=> urlencode($passback_params),
        ];

        $request->setNotifyUrl($this->_notify_url);


        //hilog::debug('###################################', $aop, $bizContent);
        $request->setBizContent(json_encode($bizContent));
        $result = $aop->execute($request);

        $responseNode = str_replace(".", "_", $request->getApiMethodName()) . "_response";
        $result = common::object_to_array($result);
        Log::debug($result);
        if (!empty($result) && isset($result[$responseNode])) {
            $result = $result[$responseNode];
            if (isset($result['code']) && $result['code'] == 10000) {
                if (isset($result['out_trade_no']) && isset($result['trade_no'])) {
                    return $result;
                }
            }
        }

        return null;
    }

    function create_trade_app($out_order_no, $amount, $subject,$pay_city)
    {
        $aop = $this->aop();
        $aop->appId = '2019091267265568';
        $request = new AlipayTradeAppPayRequest();

        $passback_params = "pay_city=".$pay_city;
        $bizContent = [
            'out_trade_no' => $out_order_no,
            'total_amount' => $amount / 100,
            'subject' => $subject,
            'product_code' => 'QUICK_MSECURITY_PAY',
            'timeout_express' => '30m',
//            'passback_params'=> urlencode($passback_params),
        ];

        $request->setNotifyUrl($this->_notify_url);


        //hilog::debug('###################################', $aop, $bizContent);
        $request->setBizContent(json_encode($bizContent));
        $result = $aop->sdkExecute($request);

        //$responseNode = str_replace(".", "_", $request->getApiMethodName()) . "_response";
        $result = common::object_to_array($result);
        Log::debug($result);
//        if (!empty($result) && isset($result[$responseNode])) {
//            $result = $result[$responseNode];
//            if (isset($result['code']) && $result['code'] == 10000) {
//                if (isset($result['out_trade_no']) && isset($result['trade_no'])) {
//                    return $result;
//                }
//            }
//        }

        return $result;
    }

    function create_trade_notify_verify($data)
    {
        $aop = $this->aop();

        $verify_result = $aop->rsaCheckV1($data, null, 'RSA2');
        Log::debug("create_trade_notify_verify:".$verify_result);
        return $verify_result;
    }

    function trade_refund($out_pay_order_id, $transaction_id, $refund_order_id, $amount, $reason)
    {
        $aop = $this->aop();
        $request = new AlipayTradeRefundRequest();
        $request->setNotifyUrl($this->_refund_notify_url);
        Log::debug("#$###################################################".$this->_refund_notify_url);
        $bizContent = [
            'out_trade_no' => $out_pay_order_id,
            'trade_no' => $transaction_id,
            'out_request_no' => $refund_order_id,
            'refund_amount' => $amount / 100,
            'refund_reason' => $reason,
        ];

        $request->setBizContent(json_encode($bizContent));
        $result = $aop->execute($request);

        $responseNode = str_replace(".", "_", $request->getApiMethodName()) . "_response";
        $result = common::object_to_array($result);
        Log::debug($result);
        if (!empty($result) && isset($result[$responseNode])) {
            $result = $result[$responseNode];
            if (isset($result['code']) && $result['code'] == 10000) {
                if (isset($result['out_trade_no']) && isset($result['trade_no'])) {
                    return $result;
                }
            }
        }

        Log::info("profit_refund_error ".$result);
    }

    function download_bill($date)
    {
        $dir = '/data/ebike/alibill';
        $file_path = $dir . '/alipay_' . $date;
        if (file_exists($file_path)) {
            return true;
        }

        if (!file_exists($dir)) {
            mkdir($dir, 0777, true);
        }


        $aop = $this->aop();

        $bizContent = [
            'bill_type' => 'trade',
            'bill_date' => $date,
        ];

        $request = new AlipayDataDataserviceBillDownloadurlQueryRequest ();
        $request->setBizContent(json_encode($bizContent));
        $result = $aop->execute($request);

        $responseNode = str_replace(".", "_", $request->getApiMethodName()) . "_response";
        $result = common::object_to_array($result);
        Log::debug($result);
        if (!empty($result) && isset($result[$responseNode])) {
            $result = $result[$responseNode];
            if (isset($result['code']) && $result['code'] == 10000) {
                if (isset($result['bill_download_url'])) {
                    $content = common::curlget($result['bill_download_url'], []);
                    if ($content) {
                        file_put_contents($file_path, $content);
                    }
                }
            }
        }
    }

    function aesdecrypt($data)
    {
        $key = base64_decode($this->_aeskey);
        $aesCipher = base64_decode($data);
        $result = openssl_decrypt($aesCipher, "AES-128-CBC", $key, 1);
        return $result;
    }

    function aes_decrypt_user_phone($data)
    {
        Log::debug($data);
        $ret = $this->aesdecrypt($data);
        Log::debug($ret);
        if (!empty($ret)) {
            $ret = json_decode($ret, true);
            if ($ret) {
                if ($ret['code'] == "10000" && isset($ret['mobile'])) {
                    return $ret['mobile'];
                }
            }
        }
        return null;
    }


    //支付宝分账功能
    function create_settle_request($out_order_no,$ali_trader_id,$receivers)
    {
        $aop = $this->aop();
        $request = new AlipayTradeOrderSettleRequest();

        $royalty_parameters = array();
        foreach ($receivers as $receiver){
            $tmpval = [
                'trans_in' => $receiver['account'],
                'amount' => $receiver['amount'] / 100,
                'description' => $receiver['desc']
            ];

            array_push($royalty_parameters,$tmpval);
        }

        $bizContent = [
            'out_request_no' => $out_order_no,
            'trade_no'=> $ali_trader_id,
            'royalty_parameters' =>$royalty_parameters
        ];

        //$request->setNotifyUrl($this->_notify_url);


        //hilog::debug('###################################', $aop, $bizContent);
        $request->setBizContent(json_encode($bizContent));
        $result = $aop->execute($request);

        $responseNode = str_replace(".", "_", $request->getApiMethodName()) . "_response";
        $result = common::object_to_array($result);
        Log::debug($result);
        if (!empty($result) && isset($result[$responseNode])) {
            $result = $result[$responseNode];
            if (isset($result['code']) && $result['code'] == 10000) {
                if (isset($result['trade_no'])) {
                    return $result;
                }
            }
        }
        Log::info("profit_error ".$result);
        return null;
    }

    //添加绑定功能
    function bind($oder_id,$account_id,$account_name)
    {
        $aop = $this->aop();

        /** 实例化具体API对应的request类，类名称和接口名称对应,当前调用接口名称：alipay.trade.royalty.relation.bind(分账关系绑定)**/
        $request = new AlipayTradeRoyaltyRelationBindRequest ();

        $bizContent = [
            'out_request_no' => $oder_id,
            'receiver_list' => array(
                array(
                    'type'=>'userId',
                    'account'=>$account_id,
                    'name'=> $account_name,
                )
            ),
        ];

        /** 设置业务参数 ,具体接口参数传值以文档说明为准：https://opendocs.alipay.com/apis/api_31/alipay.trade.royalty.relation.bind**/
        $request->setBizContent(json_encode($bizContent));

        $result= $aop->execute($request);

        /** 获取接口调用结果，如果调用失败，可根据返回错误信息到该文档寻找排查方案：https://opensupport.alipay.com/support/helpcenter/108 **/
        return json_encode($result,JSON_UNESCAPED_UNICODE);
    }

    function unbind($oder_id,$account_id,$account_name)
    {
        $aop = $this->aop();

        /** 实例化具体API对应的request类，类名称和接口名称对应,当前调用接口名称：alipay.trade.royalty.relation.bind(分账关系绑定)**/
        $request = new AlipayTradeRoyaltyRelationUnbindRequest ();

        $bizContent = [
            'out_request_no' => $oder_id,
            'receiver_list' => array(
                array(
                    'type'=>'userId',
                    'account'=>$account_id,
                    'name'=> $account_name,
                )
            ),
        ];

        /** 设置业务参数 ,具体接口参数传值以文档说明为准：https://opendocs.alipay.com/apis/api_31/alipay.trade.royalty.relation.bind**/
        $request->setBizContent(json_encode($bizContent));

        $result= $aop->execute($request);

        /** 获取接口调用结果，如果调用失败，可根据返回错误信息到该文档寻找排查方案：https://opensupport.alipay.com/support/helpcenter/108 **/
        return json_encode($result,JSON_UNESCAPED_UNICODE);
    }

    //查询
    function query($oder_id)
    {
        $aop = $this->aop();

        /** 实例化具体API对应的request类，类名称和接口名称对应,当前调用接口名称：alipay.trade.royalty.relation.bind(分账关系绑定)**/
        $request = new AlipayTradeRoyaltyRelationBatchqueryRequest();

        $bizContent = [
            'out_request_no' => $oder_id
        ];

        /** 设置业务参数 ,具体接口参数传值以文档说明为准：https://opendocs.alipay.com/apis/api_31/alipay.trade.royalty.relation.bind**/
        $request->setBizContent(json_encode($bizContent));

        $result= $aop->execute($request);

        /** 获取接口调用结果，如果调用失败，可根据返回错误信息到该文档寻找排查方案：https://opensupport.alipay.com/support/helpcenter/108 **/
        return json_encode($result,JSON_UNESCAPED_UNICODE);
    }
}
